package com.dly.blog.service;

import com.dly.blog.domain.Permission;
import com.dly.blog.domain.Role;
import com.dly.blog.domain.User;
import com.dly.blog.exception.AuthExceptionEnum;
import com.dly.blog.provider.user.PermissionProvider;
import com.dly.blog.provider.user.RoleProvider;
import com.dly.blog.provider.user.UserProvider;
import com.dly.blog.security.UserAuth;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * @Author: DaiLiYu
 * @Date: 2023/7/12 15:59
 */
@Component
@AllArgsConstructor
public class DefaultDetailsService implements UserDetailsAuthService{


    private final UserProvider userProvider;

    private final RoleProvider roleProvider;

    private final PermissionProvider permissionProvider;

    @Override
    public UserAuth loadUserByAccount(String account) {
        return Optional.ofNullable(userProvider.selectByUserAccount(account)).map(this::conversion).orElseThrow(AuthExceptionEnum.LOGIN_ERROR::getAuthException);
    }

    public UserAuth conversion(User user){
        UserAuth userAuth = new UserAuth();
        BeanUtils.copyProperties(user, userAuth);
        //todo 查询权限相关
        userAuth.setPermissions(getPermissions(userAuth.getId()));
        return userAuth;
    }

    @Override
    public UserAuth loadUserByUsername(String username) throws UsernameNotFoundException {
        return Optional.ofNullable(userProvider.selectByEmail(username)).map(this::conversion).orElseThrow(AuthExceptionEnum.LOGIN_ERROR::getAuthException);
    }

    @Override
    public UserDetails loadUserById(String id) {
        return Optional.ofNullable(userProvider.selectById(id))
                .map(this::conversion)
                .orElseThrow(AuthExceptionEnum.USER_NO::getAuthException);
    }

    @Override
    public UserDetails loadUserByOpenId(String openId) {
        return Optional.ofNullable(userProvider.selectByOpenId(openId)).map(this::conversion).orElse(null);
    }

    /**
     * 查询权限
     * @return
     */
    public Set<SimpleGrantedAuthority> getPermissions(String userId){

        List<Role> roles = roleProvider.searchAllByUserId(userId);

        List<String> roleIds = roles.stream().map(Role::getId).toList();

        List<Permission> permissions = permissionProvider.searchAllByRoleIds(roleIds);

        HashSet<SimpleGrantedAuthority> simpleGrantedAuthorities = new HashSet<>();
        //设置角色
        for (Role role: roles){
            String defaultRolePrefix = "ROLE_";
            simpleGrantedAuthorities.add(new SimpleGrantedAuthority(defaultRolePrefix +role.getRoleCode()));
        }
        //设置权限
        for (Permission permission: permissions){
            simpleGrantedAuthorities.add(new SimpleGrantedAuthority(permission.getPermissionCode()));
        }
        return simpleGrantedAuthorities;
    }
}
